import { ref } from 'vue'
import { defineStore } from 'pinia'
import queryByLayerIndex from '../apis/ol-api/queryByLayerIndex'
import queryByDraw from '../apis/ol-api/queryByDraw'
import createDraw from '../apis/ol-api/createDraw'
import addPntCallback from '../apis/ol-api/addPoint'
import setAnimateStyle from '../apis/ol-api/setAnimateStyle'
import queryPointByPosition from '../apis/ol-api/queryPointByPosition'
import { getUserInfo } from '../utils/auth'
import { setLineStyle } from '../apis/ol-api/index'
import { gaode, image } from '../apis/ol-api/layers'

export const useMapStore = defineStore('mapStore', () => {
  let map, roadSource, roadLayer
  //为了方便在store中操作地图实例
  const mapInstance = ref(null)
  // 当前点击事件的坐标
  const currentCoordinates = ref(null)
  // 抽屉可见性控制
  const drawerVisible = ref(false)
  // 抽屉标题
  const drawerTitle = ref('')
  // 当前抽屉类型
  const currentDrawerType = ref('')
  // 是否允许地图点击
  const mapClickEnabled = ref(false)
  //在OL的地图基础上加载MAPGIS发布的地图文档
  const docLayer = new Zondy.Map.Doc('地图文档', '地图文档', {
    title: '武汉光谷',
    ip: 'localhost',
    port: '6163',
  })
  //路况图层状态变量
  const roadLayerVisible = ref(false)
  //初始化地图-需要外部传入一个dom元素引用
  const initMap = (target) => {
    map = new ol.Map({
      target: target,
      view: new ol.View({
        zoom: 12,
        center: [114.37, 30.49],
        projection: 'EPSG:4326',
      }),
      layers: [gaode],
    })
    map.addLayer(docLayer)

    // 根据用户角色控制图层显示
    const userInfo = getUserInfo()
    if (userInfo && userInfo.role === 'normal') {
      // 普通用户隐藏居民区图层(索引为3)
      docLayer.setLayerStatus([3], 'exclude')
      console.log('普通用户：隐藏居民区图层')
    } else {
      // 其他用户显示所有图层
      docLayer.setLayerStatus([0, 1, 2, 3], 'include')
      console.log('管理员/交管用户：显示所有图层')
    }
    //将地图实例赋值给mapInstance
    mapInstance.value = map
    // 添加地图点击事件，统一处理所有点击
    map.on('click', (event) => {
      // 只有当允许点击时才处理
      if (!mapClickEnabled.value) return
      // 保存当前点击坐标
      currentCoordinates.value = event.coordinate
      if (
        currentDrawerType.value === 'trafficReport' ||
        mapClickEnabled.value === 'report_traffic'
      ) {
        // 设置抽屉标题和类型
        drawerTitle.value = '报告路况'
        currentDrawerType.value = 'trafficReport'
        // 显示抽屉
        drawerVisible.value = true
        // 禁用地图点击，防止重复点击
        mapClickEnabled.value = false
      }
    })
    return map
  }
  //获取地图实例
  const getMap = () => mapInstance.value
  // 初始化路况图层
  const initRoadLayer = () => {
    //如果地图不存在,则结束
    if (!map) return
    // 创建矢量源和图层
    roadSource = new ol.source.Vector()
    roadLayer = new ol.layer.Vector({
      source: roadSource,
      title: '实时路况图层',
    })
    // 添加图层到地图
    map.addLayer(roadLayer)
  }
  //一维数组转二维数组的方法,传入一维数组,返回二维数组
  const arr1ToArr2 = (arr1) => {
    let arr2 = []
    for (let i = 0; i < arr1.length; i += 2) {
      arr2.push([arr1[i], arr1[i + 1]])
    }
    return arr2
  }
  //获取发布地图的道路图层数据,返回一个对象
  const getRoadsData = async () => {
    const res = await queryByLayerIndex('地图文档', 0)
    console.log(res)
    let roadInfoArr = []
    let roadCoordArr = []
    res.forEach((item) => {
      roadInfoArr.push(item.values_.values_)
      roadCoordArr.push(item.geometryChangeKey_.target.flatCoordinates)
    })
    return { roadInfoArr, roadCoordArr }
  }
  // 显示实时路况,对路况图层进行更新
  const showRoadStatus = async () => {
    //如果路况图层不存在,则结束
    if (!roadSource) return
    // 清空现有的要素
    roadSource.clear()
    //获取路况图层数据
    const { roadInfoArr, roadCoordArr } = await getRoadsData()
    //遍历路况图层数据
    roadInfoArr.forEach((roadInfo, index) => {
      // 转换坐标为二维数组
      const roadCoord2 = arr1ToArr2(roadCoordArr[index])
      // 设置道路颜色 (从大到小判断)
      let roadColor = 'green'
      const trafficVolume = parseInt(roadInfo.车流量 || 0)
      if (trafficVolume > 1600) {
        roadColor = 'red'
      } else if (trafficVolume > 1200) {
        roadColor = 'orange'
      } else if (trafficVolume > 800) {
        roadColor = 'yellow'
      }
      // 创建线要素
      const roadFeature = new ol.Feature({
        geometry: new ol.geom.LineString(roadCoord2),
        name: roadInfo.道路名称,
        trafficVolume,
      })
      // 设置样式
      roadFeature.setStyle(setLineStyle({ color: roadColor, width: 5 }))
      // 添加要素到道路资源
      roadSource.addFeature(roadFeature)
    })
  }
  // 保存表单数据到地图
  const saveTrafficReport = async (formValues) => {
    try {
      if (!currentCoordinates.value) {
        ElMessage.error('未获取到地图点击位置')
        return false
      }
      // 创建一个事件对象
      const event = { coordinate: currentCoordinates.value }
      // 调用addPntCallback添加点要素
      addPntCallback(event, formValues, docLayer)
      // 添加点后查询图层数据
      const res = await queryByLayerIndex('地图文档', 4)
      console.log('添加后的图层数据:', res)
      ElMessage.success('事件信息添加成功!')
      return true
    } catch (error) {
      console.error('添加事件信息时发生错误:', error)
      ElMessage.error('添加事件信息失败!')
      return false
    }
  }
  //实现报告路况功能
  const reportTraffic = () => {
    ElMessage.success('选择位置并添加事件信息')
    // 启用地图点击并标记为报告路况模式
    mapClickEnabled.value = 'report_traffic'
  }
  //获取发布地图的事件图层数据,返回一个对象
  const getEventsData = async () => {
    const res = await queryByLayerIndex('地图文档', 4)
    let eventInfoArr = []
    let eventCoordArr = []
    res.forEach((item) => {
      eventInfoArr.push(item.values_.values_)
      eventCoordArr.push(item.geometryChangeKey_.target.flatCoordinates)
    })
    return { eventInfoArr, eventCoordArr }
  }
  //实现事件查询(拉框查询)
  const queryEvent = async () => {
    const res = await getEventsData()
    console.log(res)
    ElMessage.success('开始绘制')
    //创建事件图层和资源
    let eventSource = new ol.source.Vector()
    let eventLayer = new ol.layer.Vector({
      source: eventSource,
      title: '查询事件图层',
      style: setAnimateStyle({
        map,
        src: '/icon.png',
      }),
    })
    map.addLayer(eventLayer)
    // 返回一个Promise以便外部获取查询结果
    return new Promise((resolve) => {
      //初始化一个画笔
      const draw = createDraw({
        type: 'Polygon',
        source: eventSource,
      })
      map.addInteraction(draw)
      draw.on('drawend', function (e) {
        //完成绘制 查询当前范围内的要素
        let g = e.feature.getGeometry()
        queryByDraw(g).then((res) => {
          if (res) {
            console.log('查询到的事件数据', res)
            //清除之前的
            eventSource.clear()
            //添加新圈中的
            eventSource.addFeatures(res)
            //移除画笔
            map.removeInteraction(draw)
            // 计算选区的范围
            const extent = e.feature.getGeometry().getExtent()
            // 返回查询结果和选区范围
            resolve({
              features: res,
              extent: extent,
            })
          } else {
            resolve({ features: [], extent: null })
          }
        })
      })
    })
  }

  // 获取拉框范围内的事件数据
  const getQueryEventData = (features) => {
    if (!features || features.length === 0) return []

    const eventDataArray = []

    features.forEach((feature) => {
      // 从features中获取values_对象，这与getRoadsData()中的数据获取方式相似
      const values = feature.get('values_')
      if (values) {
        // 提取需要的事件属性
        eventDataArray.push({
          eventId: values.事件编号 || '未知',
          eventType: values.事件类型 || '未知',
          eventLevel: values.事件等级 || '未知',
          eventTime: values.发生时间 || '未知',
          eventLocation: values.发生地点 || '未知',
          carNumber: values.车牌号 || '',
          driver: values.驾驶员 || '',
          processStatus: values.处理状态 || '0',
        })
      }
    })

    return eventDataArray
  }
  // 禁用地图点击
  const disableMapClick = () => {
    mapClickEnabled.value = false
  }
  // 清除事件图层和查询结果
  const clearEventGraphics = () => {
    // 获取所有图层
    const layers = map.getLayers().getArray()

    // 查找事件图层
    const eventLayers = layers.filter(
      (layer) =>
        layer.get('title') === '查询事件图层' ||
        layer.get('title') === '高亮事件图层'
    )

    // 如果找到事件图层，移除它们
    eventLayers.forEach((layer) => {
      map.removeLayer(layer)
    })

    // 移除所有绘图交互
    map
      .getInteractions()
      .getArray()
      .forEach((interaction) => {
        if (interaction instanceof ol.interaction.Draw) {
          map.removeInteraction(interaction)
        }
      })

    // 同时清除热力图层
    clearHeatMapLayer()
  }

  // 清除热力图层
  const clearHeatMapLayer = () => {
    const layers = map.getLayers().getArray()

    // 查找热力图层和边框图层
    const heatmapLayers = layers.filter(
      (layer) =>
        layer.get('title') === '事件热力图层' ||
        layer.get('title') === '热力图边框图层'
    )
    // 移除找到的图层
    heatmapLayers.forEach((layer) => {
      map.removeLayer(layer)
    })
    console.log('已清除热力图层', heatmapLayers.length, '个')
  }
  // 添加热力图层
  const addHeatMapLayer = (data, options = {}) => {
    // 首先清除旧的热力图层
    clearHeatMapLayer()
    if (!data || data.length === 0) return
    try {
      console.log('添加热力图层，数据:', data.length, '点，设置:', options)
      // 创建热力图数据源
      const heatmapFeatures = data.map((item) => {
        const feature = new ol.Feature({
          geometry: new ol.geom.Point(item.coordinates),
          weight: item.weight,
          eventType: item.eventType,
        })
        return feature
      })
      const heatmapSource = new ol.source.Vector({
        features: heatmapFeatures,
      })
      // 创建热力图层
      const heatmapLayer = new ol.layer.Heatmap({
        source: heatmapSource,
        title: '事件热力图层',
        blur: options.blur || 15,
        radius: options.radius || 20,
        opacity: 0.8,
        gradient: [
          'rgba(0,0,255,0.5)',
          'rgba(0,255,0,0.5)',
          'rgba(255,255,0,0.5)',
          'rgba(255,0,0,0.8)',
        ],
        zIndex: 99, // 确保显示在其他图层之上
      })
      // 添加到地图
      map.addLayer(heatmapLayer)
      // 如果需要显示边框
      if (options.showBorder) {
        // 为每个热力点添加边框图层
        const borderSource = new ol.source.Vector({
          features: heatmapFeatures.map((feature) => {
            // 克隆要素以便单独设置样式
            const borderFeature = feature.clone()
            // 设置边框样式
            borderFeature.setStyle(
              new ol.style.Style({
                image: new ol.style.Circle({
                  radius: 5,
                  stroke: new ol.style.Stroke({
                    color: '#fff',
                    width: 2,
                  }),
                  fill: new ol.style.Fill({
                    color: 'rgba(0, 0, 0, 0)',
                  }),
                }),
              })
            )
            return borderFeature
          }),
        })
        // 创建边框图层
        const borderLayer = new ol.layer.Vector({
          source: borderSource,
          title: '热力图边框图层',
          zIndex: 100,
        })
        // 添加边框图层
        map.addLayer(borderLayer)
      }
    } catch (error) {
      console.error('添加热力图层失败:', error)
    }
  }
  // 平移地图到指定位置
  const panToLocation = (coordinates) => {
    if (!map || !coordinates) return
    // 平移地图到指定坐标位置
    map.getView().animate({
      center: coordinates,
      duration: 500,
    })
  }
  // 高亮显示指定要素
  const highlightFeature = (feature) => {
    // 如果没有要素，则不执行操作
    if (!feature) return
    // 清除之前的高亮图层
    const layers = map.getLayers().getArray()
    const highlightLayer = layers.find(
      (layer) => layer.get('title') === '高亮事件图层'
    )
    if (highlightLayer) {
      map.removeLayer(highlightLayer)
    }
    // 创建一个新图层用于高亮显示
    const highlightSource = new ol.source.Vector()
    const highlightStyle = new ol.style.Style({
      image: new ol.style.Circle({
        radius: 12,
        fill: new ol.style.Fill({
          color: 'rgba(255, 255, 0, 0.5)',
        }),
        stroke: new ol.style.Stroke({
          color: '#ff0000',
          width: 2,
        }),
      }),
    })
    // 添加要素到高亮图层
    highlightSource.addFeature(feature)
    // 创建高亮图层
    const newHighlightLayer = new ol.layer.Vector({
      source: highlightSource,
      title: '高亮事件图层',
      style: highlightStyle,
      zIndex: 100, // 确保显示在其他图层之上
    })
    // 添加高亮图层到地图
    map.addLayer(newHighlightLayer)
  }
  // 清除所有地图交互（画笔等）
  const clearInteractions = () => {
    if (!map) return
    // 获取所有交互
    const interactions = map.getInteractions().getArray()
    // 找到所有绘图交互
    const drawInteractions = interactions.filter(
      (interaction) => interaction instanceof ol.interaction.Draw
    )
    // 移除所有绘图交互
    drawInteractions.forEach((interaction) => {
      map.removeInteraction(interaction)
    })
    console.log('已经清除所有绘图交互')
  }
  // 切换路况图层显示/隐藏
  const toggleRoadLayer = async () => {
    if (!map) return false
    // 如果没有初始化路况图层，先初始化
    if (!roadLayer) {
      initRoadLayer()
    }
    // 切换显示状态
    roadLayerVisible.value = !roadLayerVisible.value
    if (roadLayerVisible.value) {
      // 显示路况并加载数据
      await showRoadStatus()
      console.log('显示路况图层')
      return true
    } else {
      // 隐藏路况图层
      if (roadLayer) {
        roadSource.clear()
        console.log('隐藏路况图层')
      }
      return false
    }
  }
  // 获取路况图层可见状态
  const getRoadLayerVisible = () => roadLayerVisible.value
  //获取监控点图层数据
  const getMonitorPointData = async () => {
    const res = await queryByLayerIndex('地图文档', 2)
    let monitorInfoArr = []
    let monitorCoordArr = []
    res.forEach((item) => {
      monitorInfoArr.push(item.values_.values_)
      monitorCoordArr.push(item.geometryChangeKey_.target.flatCoordinates)
    })
    return { monitorInfoArr, monitorCoordArr }
  }
  // 获取文档图层
  const getDocLayer = () => {
    return docLayer
  }
  return {
    arr1ToArr2,
    getRoadsData,
    initMap,
    initRoadLayer,
    showRoadStatus,
    reportTraffic,
    getMap,
    queryEvent,
    getQueryEventData,
    clearEventGraphics,
    clearHeatMapLayer,
    addHeatMapLayer,
    panToLocation,
    highlightFeature,
    // 侧边抽屉相关
    drawerVisible,
    drawerTitle,
    currentDrawerType,
    currentCoordinates,
    saveTrafficReport,
    // 地图点击控制
    mapClickEnabled,
    disableMapClick,
    clearInteractions,
    // 路况图层控制
    toggleRoadLayer,
    getRoadLayerVisible,
    // 监控点图层控制
    getMonitorPointData,
    queryPointByPosition,
    // 添加获取文档图层的方法
    getDocLayer,
  }
})
